﻿using System;
using System.Text;
using System.Xml;
using System.Globalization;
using InfoJetSoft.Service.Entity;

namespace InfoJetSoft.Service.Util
{
	
	class NumberFormater
	{	

		//根据TypeFormat格式化.
		//如果XmlNode已格式化,setNodeValue=flase,表示是在Xslt中调用,不需要设置XmNode的值,只需要返回格式化后的值.
		//如果XmlNode未格式花,setNodeValue=true,表示由FormValueValueChangeDeformatWorker调用,需要使用NumberValue设置XmlNode.
		//同时此时,NumberValue必须符合Xml Schema,如在Dutch语言下,32.34 + ""返回32,34,必须将32,34替换为32.34.
		//[还有一种情况是不符合Xml Schema,但是可以进行格式化,如一int类型的字段,输入1.1,不符合Schema,但可以被格式化成1,见CSPF.xsn.
		//这种情况下,如果该字端类型已知则可以在客户端格式化成功,如未知则必须在服务端格式化.
		//Schema未知,但可以格式化,页面将显示正确值如1,但是因为是在ValueChange中,Xml值仍是1.1,所以就会在页面字段1的值上显示无效边框.
		//解决的办法就是尽量判断schema.] 新的代码[1]尝试先处理这种情况.
		public static string format(Form form, XmlNode node, string value_Renamed, TypeFormat typeFormat, bool setNodeValue, bool nodeValueFormatted)
		{
			if (value_Renamed.Trim().Length <= 0)
			{
				return "";
			}

			//CID 0116 //2008.09.15 //Comment
			/*
			//代码[1],如果要格式化一个包含NumberDecimalSeparator的整型数字,直接返回,按格式化出错处理.
			//但是这样不能支持将double格式化成integer.
			if( typeFormat.NumDigits != null && typeFormat.NumDigits.Equals( "0" ) )
			{
				CultureInfo culcutre = LocaleUtil.getLocale( typeFormat );
				if( value_Renamed.IndexOf( culcutre.NumberFormat.NumberDecimalSeparator ) >= 0 )
				{
					return value_Renamed;
				}
			}
			*/
			//CID 0116 //2008.09.15 //Comment
			
			bool isPercentage = false;
			if (typeFormat.Type != null && typeFormat.Type.Equals(NumberFormat.Percentage))
			{
				isPercentage = true;
			}

			string deformatedValue = deformat(value_Renamed, typeFormat);
			double doubleValue = 0;
			double percentageValue = 0;
			try
			{
				deformatedValue = toLocaleString4Parse( deformatedValue, nodeValueFormatted );
				doubleValue = System.Double.Parse( deformatedValue );
				if( isPercentage ){
					if( setNodeValue ){
                        //CID 0700 //2010.11.05 //Begin
                        if (nodeValueFormatted)
                        {
                            percentageValue = doubleValue;
                        }
                        else
                        {
                            percentageValue = doubleValue / 100.0;
                        }
                        //CID 0700 //2010.11.05 //End
					}else{
						percentageValue = doubleValue;
						doubleValue = doubleValue * 100.0;
					}
				}
			}
			catch (System.FormatException nfe)
			{
				return value_Renamed;
			}

			if( setNodeValue )
			{
				string nodeValue = null;
				if( isPercentage )
				{
                    nodeValue = percentageValue + "";
				}
				else
				{
					nodeValue = doubleValue + "";
				}
				nodeValue = toXmlString( nodeValue );
				FormUtil.updateFormattingNode(form, node, nodeValue);
			}

			return NumberFormater.format(doubleValue, typeFormat);
		}

		private static string toLocaleString4Parse( string deformatedValue, bool nodeValueFormatted )
		{
			if( nodeValueFormatted )
			{
				//如果已经nodeValueFormatted,表示值是从Xml文件中提取的,或者是经infojet.js格式化的,使用"."作为NumberDecimalSeparator.
				//但是使用System.Double.Parse需要提供本地的NumberDecimalSeparator,所以这里要进行替换.
				//已经格式化的NodeValue只包含".",如123456.78,如果包含".",那替换为服务器本地NumberDecimalSeparator.
				deformatedValue = deformatedValue.Replace( ".", System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator );
				return deformatedValue;
			}
			else
			{
				//未nodeValueFormatted,表示是infojet.js提交上来,但未经过infojet.js进行数字格式化.
				//可能是33.233,53或35,232,12,这里只需要删除NumberGroupSeparator.
				//如果传入的是abc,那么是肯定不能格式化的,去掉NumberGroupSeparator只是尽量尝试能正确格式化.
				deformatedValue = deformatedValue.Replace( System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberGroupSeparator, "" );
				return deformatedValue;
			}
		}

		private static string toXmlString( string localeString )
		{
			//将NumberDecimalSeparator替换为XmlSchema标准的"."
			//localeString是 32.34 + "" = "32,34", 这里要将"32,34"转化为"32.34",既XML数字格式.
			localeString = localeString.Replace( System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator, "." );
			return localeString;
		}

		private static NumberFormat TypeFormat2NumberFormat( TypeFormat typeFormat ){
			NumberFormat numberFormat = new NumberFormat();
			numberFormat.Type = typeFormat.Type;
			//currency symbol,locale,culture
			LocaleUtil.setCultureCurrencyLocaleSymbol( typeFormat, numberFormat );
			//grouping
			if (typeFormat.Grouping != null) {
				if (!typeFormat.Grouping.Equals("0")) {
					numberFormat.GroupingUsed = true;
				}
				else {
					numberFormat.GroupingUsed = false;
				}
			}
			else {
				numberFormat.GroupingUsed = true;
			}
			//numDigits
			if (typeFormat.NumDigits != null && (!typeFormat.NumDigits.Equals("auto"))) {
				try {
					int numDigits = System.Int32.Parse(typeFormat.NumDigits);
					numberFormat.MinFractionDigits = numDigits;
				}
				catch (System.FormatException nfe) {
				}
			}
			//negativeOrder
			if (typeFormat.NegativeOrder != null ) {
				try {
					int negativeOrder = System.Int32.Parse(typeFormat.NegativeOrder);
					numberFormat.NegativePattern = negativeOrder;
				}
				catch (System.FormatException nfe) {
				}
			}else{
				numberFormat.NegativePattern = 2;
			}
			//positiveOrder
			if (typeFormat.PositiveOrder != null ) {
				try {
					int positiveOrder = System.Int32.Parse(typeFormat.PositiveOrder);
					numberFormat.PositivePattern = positiveOrder;
				}
				catch (System.FormatException nfe) {
				}
			}else{
				numberFormat.PositivePattern = 0;
			}
			return numberFormat;
		}
		
		private static string format(double doubleValue, TypeFormat typeFormat)
		{
			NumberFormat numberFormat = TypeFormat2NumberFormat( typeFormat );
			string value_Renamed = numberFormat.Format(doubleValue);
			return value_Renamed;
		}
		
		private static string deformat(string value_Renamed, TypeFormat typeFormat)
		{
			bool isNegative = false;
			string currency = LocaleUtil.getCurrencySymbol(typeFormat);
			value_Renamed = value_Renamed.Trim();
			if (value_Renamed.StartsWith("(") && value_Renamed.EndsWith(")"))
			{
				value_Renamed = value_Renamed.Substring(1, (value_Renamed.Length - 1) - (1));
				isNegative = true;
				value_Renamed = value_Renamed.Trim();
				value_Renamed = trimCurrency(value_Renamed, currency);
			}
			else
			{
				value_Renamed = value_Renamed.Trim();
				value_Renamed = trimCurrency(value_Renamed, currency);
				value_Renamed = value_Renamed.Trim();
				if (value_Renamed.StartsWith("-") && (!value_Renamed.EndsWith("-")))
				{
					value_Renamed = value_Renamed.Substring(1, (value_Renamed.Length) - (1));
					isNegative = true;
				}
				if ((!value_Renamed.StartsWith("-")) && value_Renamed.EndsWith("-"))
				{
					value_Renamed = value_Renamed.Substring(0, (value_Renamed.Length - 1) - (0));
					isNegative = true;
				}
				value_Renamed = value_Renamed.Trim();
				value_Renamed = trimCurrency(value_Renamed, currency);
			}
			value_Renamed = value_Renamed.Trim();
			if (isNegative)
			{
				value_Renamed = "-" + value_Renamed;
			}
			return value_Renamed;
		}
		
		private static string trimCurrency(string value_Renamed, string currency)
		{
			if (value_Renamed.StartsWith(currency))
			{
				value_Renamed = value_Renamed.Substring(currency.Length, (value_Renamed.Length) - (currency.Length));
				value_Renamed = value_Renamed.Trim();
			}
			if (value_Renamed.EndsWith(currency))
			{
				value_Renamed = value_Renamed.Substring(0, (value_Renamed.Length - currency.Length) - (0));
				value_Renamed = value_Renamed.Trim();
			}
			return value_Renamed;
		}

	}
}